package com.example.leetcode.c501_c600.c501;
/**
 * 给定一个有相同值的二叉搜索树（BST），找出 BST 中的所有众数（出现频率最高的元素）。
 *
 * 假定 BST 有如下定义：
 *
 * 结点左子树中所含结点的值小于等于当前结点的值
 * 结点右子树中所含结点的值大于等于当前结点的值
 * 左子树和右子树都是二叉搜索树
 * 例如：
 * 给定 BST [1,null,2,2],
 *
 *    1
 *     \
 *      2
 *     /
 *    2
 * 返回[2].
 *
 * 提示：如果众数超过1个，不需考虑输出顺序
 *
 * 进阶：你可以不使用额外的空间吗？（假设由递归产生的隐式调用栈的开销不被计算在内）
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/find-mode-in-binary-search-tree
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */

import com.example.leetcode.common.TreeNode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 二叉搜索树中的众数
 * @author zhanpengguo
 * @date 2020-09-24 8:12
 */
public class Solution {

    private int[] res;
    private List<Integer> list = new ArrayList<>();
    private Integer pre = null;
    private Integer cur = null;
    private int curCount = 0;
    private int maxCount = 0;

    // 中序遍历是个有序数组
    public int[] findMode(TreeNode root) {
        if (root == null) {
            return new int[]{};
        }
        pre = root.val;
        digui(root);
        res = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            res[i] = list.get(i);
        }
        return res;
    }

    private void digui(TreeNode root) {
        if (root == null) {
            return;
        }
        digui(root.left);
        cur = root.val;
        if (cur.equals(pre)) {
            curCount++;
        } else {
            pre = cur;
            curCount = 1;
        }
        if (curCount > maxCount) {
            maxCount = curCount;
            list.clear();
            list.add(cur);
        } else if (curCount == maxCount) {
            list.add(cur);
        } else {

        }
        digui(root.right);
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        TreeNode root = new TreeNode(1);
        TreeNode right = new TreeNode(2);
        right.left = new TreeNode(2);
        root.right = right;
        int[] mode = solution.findMode(root);
        System.out.println(Arrays.toString(mode));
    }
}
